/*
 * Copyright 2022. Huawei Technologies Co., Ltd. All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.huawei.mlkit.test.example.body.interactiveLivenessdetection;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.huawei.hms.mlsdk.interactiveliveness.MLInteractiveLivenessCapture;
import com.huawei.hms.mlsdk.interactiveliveness.MLInteractiveLivenessCaptureConfig;
import com.huawei.hms.mlsdk.interactiveliveness.MLInteractiveLivenessCaptureResult;
import com.huawei.hms.mlsdk.interactiveliveness.action.MLInteractiveLivenessConfig;
import com.huawei.mlkit.test.example.R;
import com.huawei.mlkit.test.example.common.CostTimeUtils;

public class LiveInteractiveLivenessDetectionActivity extends AppCompatActivity {
    private static final String TAG = LiveInteractiveLivenessDetectionActivity.class.getSimpleName();

    private static final String[] PERMISSIONS = {
            Manifest.permission.CAMERA
    };

    private static final int RC_CAMERA_AND_EXTERNAL_STORAGE_DEFAULT = 0x01 << 8;

    private Button defaultBtn;
    @SuppressLint("StaticFieldLeak")
    private static TextView mTextResult;
    @SuppressLint("StaticFieldLeak")
    private static ImageView mImageResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_interactive_liveness_detection);

        defaultBtn = findViewById(R.id.capture_btn);
        mTextResult = findViewById(R.id.text_detect_result);
        mImageResult = findViewById(R.id.img_detect_result);

        defaultBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ActivityCompat.checkSelfPermission(LiveInteractiveLivenessDetectionActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                    CostTimeUtils.getInstance().setStartTime(System.currentTimeMillis());
                    startCaptureActivity();
                    return;
                }
                ActivityCompat.requestPermissions(LiveInteractiveLivenessDetectionActivity.this, PERMISSIONS, RC_CAMERA_AND_EXTERNAL_STORAGE_DEFAULT);
            }
        });
    }

    private static MLInteractiveLivenessCapture.Callback callback = new MLInteractiveLivenessCapture.Callback() {
        /**
         * Liveness detection success callback.
         * @param result result
         */
        @Override
        public void onSuccess(MLInteractiveLivenessCaptureResult result) {
            mTextResult.setText(new StringBuffer().append(result.toString())
                    .append("\n StateCode is:" + result.getStateCode())
                    .append("\n Default success cost(ms): " + (System.currentTimeMillis() - CostTimeUtils.getInstance().getStartTime())));
            mTextResult.setBackgroundResource(result.getScore() > 0.8 ? R.drawable.bg_blue : R.drawable.bg_red);
            if (result.getBitmap() != null) {
                mImageResult.setImageBitmap(result.getBitmap());
            }
        }

        @Override
        public void onFailure(int errorCode) {
            mTextResult.setText("errorCode:" + errorCode);
        }
    };

    public static final MLInteractiveLivenessCapture.Callback customCallback = new MLInteractiveLivenessCapture.Callback() {
        /**
         * Liveness detection success callback.
         * @param result result
         */
        @Override
        public void onSuccess(MLInteractiveLivenessCaptureResult result) {
            mTextResult.setText(new StringBuilder()
                    .append("MLInteractiveLivenessCaptureResult{ ActionType:").append(result.getActionType())
                    .append(",StateCode:").append(result.getStateCode())
                    .append(",FrameNum:").append(result.getFrameNum())
                    .append(",Score:").append(result.getScore()).append(" }")
                    .append("\n Default success cost(ms): " + (System.currentTimeMillis() - CostTimeUtils.getInstance().getStartTime()))
                    .toString());
            mTextResult.setBackgroundResource(result.getScore() > 0.8 ? R.drawable.bg_blue : R.drawable.bg_red);
            mImageResult.setImageBitmap(result.getBitmap());
        }

        @Override
        public void onFailure(int errorCode) {
            mTextResult.setText("errorCode:" + errorCode);
        }
    };

    private void startCaptureActivity() {
        MLInteractiveLivenessConfig interactiveLivenessConfig = new MLInteractiveLivenessConfig.Builder().build();

        MLInteractiveLivenessCaptureConfig captureConfig = new MLInteractiveLivenessCaptureConfig.Builder()
                .setOptions(MLInteractiveLivenessCaptureConfig.DETECT_MASK)
                .setActionConfig(interactiveLivenessConfig)
                .setDetectionTimeOut(10000)
                .build();
        MLInteractiveLivenessCapture capture = MLInteractiveLivenessCapture.getInstance();
        capture.setConfig(captureConfig);
        capture.startDetect(this, callback);
        Toast.makeText(this, "Default build cost(ms): " + (System.currentTimeMillis() - CostTimeUtils.getInstance().getStartTime()), Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.i(TAG, "onRequestPermissionsResult ");
        if (requestCode == RC_CAMERA_AND_EXTERNAL_STORAGE_DEFAULT && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startCaptureActivity();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        Log.i(TAG, "onActivityResult requestCode " + requestCode + ", resultCode " + resultCode);
    }
}
